﻿using System;
using System.Collections.Generic;
using System.Linq;
using Microsoft.Xna.Framework;
using Microsoft.Xna.Framework.Audio;
using Microsoft.Xna.Framework.Content;
using Microsoft.Xna.Framework.GamerServices;
using Microsoft.Xna.Framework.Graphics;
using Microsoft.Xna.Framework.Input;
using Microsoft.Xna.Framework.Media;


namespace Poke_Tactics.Main_Game
{
    class Main_Map
    {

        #region atributos



        public GameWindow Window;

        public Vector2 testPos;


        public Texture2D map;
        public Texture2D mainworld_menu;

        public Camera camera { get { return Game1.cameraAtual; } set { Game1.cameraAtual = value; } }

        protected float alfa;


        public float Alfa
        {
            get { return alfa; }

            set
            {
                if (value >= 0 && value <= 1)
                {
                    alfa = value;
                }
                else
                {
                    alfa = 1;
                }
            }
        }


        public Button enterMap;
        public Button returnToMap;

        public Button pokeDex, pokemons, items, status, options;



        // Lugares do map
        public struct MapPlaces
        {
            public Texture2D markSprite;
            public Rectangle colisionSquare;
            public bool visited;
            public string name;
            public Vector2 position;
            public Texture2D placeTitle;
            public bool placeTitleVisible;
        }

        public MapPlaces[] placeList;
        public MapPlaces currentPlace;

        public Object player;

        #endregion

        #region métodos

        public Main_Map(GameWindow Window, ContentManager Content)
        {

            this.Window = Window;
            this.player = new Object(Content.Load<Texture2D>("Player/player1"), Window, 32, 32, 3, 2, false, false);
            this.player.Posicao = new Vector2(241, 856);


            mainworld_menu = Content.Load<Texture2D>("menu_mainworld");

            pokeDex = new Button(Window, Content.Load<Texture2D>("PokeDex"));
            pokemons = new Button(Window, Content.Load<Texture2D>("Pokemons"));
            items = new Button(Window, Content.Load<Texture2D>("Items"));
            status = new Button(Window, Content.Load<Texture2D>("Status"));
            options = new Button(Window, Content.Load<Texture2D>("Options"));



            this.player.addAnimation(Content.Load<Texture2D>("Player/player1"), 32, 32, 3, 8, "Up", true, false);
            this.player.addAnimation(Content.Load<Texture2D>("Player/player2"), 32, 32, 3, 8, "Right", true, false);
            this.player.addAnimation(Content.Load<Texture2D>("Player/player3"), 32, 32, 3, 8, "Down", true, false);
            this.player.addAnimation(Content.Load<Texture2D>("Player/player4"), 32, 32, 3, 8, "Left", true, false);

            this.enterMap = new Button(Window, Content.Load<Texture2D>("Enter"));
           
            this.returnToMap = new Button(Window, Content.Load<Texture2D>("Return_Button"));


            this.alfa = 1;
            this.map = Content.Load<Texture2D>("Kanto");
            testPos = new Vector2();
            placeList = new MapPlaces[8];

            #region Cidades

            placeList[0] = new MapPlaces();
            placeList[0].markSprite = Content.Load<Texture2D>("city_icon");
            placeList[0].visited = true;
            placeList[0].position = new Vector2(241, 856);
            placeList[0].colisionSquare = new Rectangle(241, 856, placeList[0].markSprite.Width, placeList[0].markSprite.Height);
            placeList[0].name = "Pallet";
            placeList[0].placeTitle = Content.Load<Texture2D>("City/Pallet_String");
            placeList[0].placeTitleVisible = false;
            currentPlace = placeList[0];

            placeList[1] = new MapPlaces();
            placeList[1].markSprite = Content.Load<Texture2D>("danger_icon");
            placeList[1].visited = false;
            placeList[1].position = new Vector2(237, 780);
            placeList[1].colisionSquare = new Rectangle(237, 780, placeList[1].markSprite.Width, placeList[1].markSprite.Height);
            placeList[1].name = "Route 1";
            placeList[1].placeTitle = Content.Load<Texture2D>("City/Route1_String");
            placeList[1].placeTitleVisible = false;

            placeList[2] = new MapPlaces();
            placeList[2].markSprite = Content.Load<Texture2D>("city_icon");
            placeList[2].visited = false;
            placeList[2].position = new Vector2(237, 701);
            placeList[2].colisionSquare = new Rectangle(237, 701, placeList[2].markSprite.Width, placeList[2].markSprite.Height);
            placeList[2].name = "Viridian";
            placeList[2].placeTitle = Content.Load<Texture2D>("City/Viridian_String");
            placeList[2].placeTitleVisible = false;



            

            #endregion
        }

        public void Update(GameTime gameTime, Vector2 mousePos, MouseState mouse, MouseState old_mouse, KeyboardState keyboard)
        {
            #region cameraZoom
            if (mouse.ScrollWheelValue > old_mouse.ScrollWheelValue)
            {
                if(camera.zoom <= 1.6f)
                camera.zoom += 0.05f;
            }

            if (mouse.ScrollWheelValue < old_mouse.ScrollWheelValue)
            {
                if (camera.zoom > 1.05f)
                camera.zoom -= 0.05f;
            }
            #endregion


            enterMap.isVisible = false;

            for (uint i = 0; i < placeList.Length; i++)
            {
                if (placeList[i].markSprite != null)
                {
                    if (placeList[i].colisionSquare.Intersects(new Rectangle((int)mousePos.X, (int)mousePos.Y, 1, 1)))
                    {
                        if (currentPlace.name == placeList[i].name && !player.isWalking)
                        {
                            enterMap.isVisible = true;
                            enterMap.position = placeList[i].position;
                        }
                       

                        placeList[i].placeTitleVisible = true;
                        if (mouse.LeftButton == ButtonState.Pressed)
                        {
                            if (!player.isWalking)
                            {
                                player.walkWay = getRoute(player.Posicao, placeList[i].position);
                                player.isWalking = true;
                                currentPlace = placeList[i];
                            }
                        }
                    }
                    else
                    {
                        placeList[i].placeTitleVisible = false;
                    }
                }
            }

            enterMap.Update(gameTime, mousePos, mouse, old_mouse);
            returnToMap.Update(gameTime, mousePos, mouse, old_mouse);

            if (keyboard.IsKeyDown(Keys.W))
            {
                this.player.changeAnimation("Up");
                //placeList[2].position = new Vector2(placeList[2].position.X, placeList[2].position.Y - 1);
            }

            if (keyboard.IsKeyDown(Keys.D))
            {
                this.player.changeAnimation("Right");
                //placeList[2].position = new Vector2(placeList[2].position.X + 1, placeList[2].position.Y);
            }

            if (keyboard.IsKeyDown(Keys.S))
            {
                this.player.changeAnimation("Down");
                //placeList[2].position = new Vector2(placeList[2].position.X, placeList[2].position.Y + 1);
            }

            if (keyboard.IsKeyDown(Keys.A))
            {
                this.player.changeAnimation("Left");
                //placeList[2].position = new Vector2(placeList[2].position.X - 1, placeList[2].position.Y);
            }

            

            if(keyboard.IsKeyDown(Keys.Enter))
            {
                Console.WriteLine(Window.ClientBounds.Width + " / "+Window.ClientBounds.Height);
            }


            
                if (player.isWalking)
                {
                    if (player.walkWay.Count >= 1)
                    {
                        Vector2 toPosition = player.walkWay[0];
                        player.walkWay.Remove(toPosition);
                        player.changeAnimation(getDirectionTo(toPosition, player.Posicao));
                        
                        player.Posicao = toPosition;
                    }
                    else
                    {
                        player.isWalking = false;
                    }

                }



                camera.position = this.player.Posicao;

        }

        public void Draw(GameTime gameTime, SpriteBatch spriteBatch)
        {

            player.Draw(gameTime, spriteBatch);


            enterMap.Draw(gameTime, spriteBatch);
            returnToMap.Draw(gameTime, spriteBatch);

            #region mapMarks
            for (uint i = 0; i < placeList.Length; i++)
            {
                if (placeList[i].markSprite != null)
                {
                    spriteBatch.Draw(placeList[i].markSprite, placeList[i].position, new Rectangle(0, 0, placeList[i].markSprite.Width, placeList[i].markSprite.Height * 1), new Color(1.0f * alfa, 1.0f * alfa, 1.0f * alfa, 1.0f * alfa), 0, new Vector2(), 0.3f, SpriteEffects.None,0.5f);
                    if (placeList[i].placeTitleVisible && currentPlace.name != placeList[i].name)
                    {
                        spriteBatch.Draw(placeList[i].placeTitle, placeList[i].position, new Rectangle(0, 0, placeList[i].placeTitle.Width, placeList[i].placeTitle.Height * 1), new Color(1.0f * alfa, 1.0f * alfa, 1.0f * alfa, 1.0f * alfa), 0, new Vector2(), 1.0f, SpriteEffects.None, 0);
                    }
                    
                }
            }
            #endregion
            
            spriteBatch.Draw(map, new Vector2(19, 382), new Rectangle(0, 0, map.Width, map.Height * 1), new Color(1.0f * alfa, 1.0f * alfa, 1.0f * alfa, 1.0f * alfa), 0, new Vector2(), 1f, SpriteEffects.None, 1);

            spriteBatch.Draw(mainworld_menu, new Vector2(0, 400), new Rectangle(0, 0, mainworld_menu.Width, mainworld_menu.Height), new Color(1.0f * alfa, 1.0f * alfa, 1.0f * alfa, 1.0f * alfa), 0, new Vector2(), 1f, SpriteEffects.None, 0.1f);
        }

        public List<Vector2> getRoute(Vector2 fromPosition, Vector2 toPosition)
        {

            Vector2 nextPos = fromPosition;
            List<Vector2> route = new List<Vector2>();

            do
            {
                if ((nextPos.X != toPosition.X) && (nextPos.Y != toPosition.Y))
                {
                    nextPos.X = nextPos.X + ((toPosition.X > nextPos.X) ? 1 : -1);
                    route.Add(nextPos);
                    nextPos.Y = nextPos.Y + ((toPosition.Y > nextPos.Y) ? 1 : -1);
                    route.Add(nextPos);
                }
                else
                {
                    if (nextPos.X != toPosition.X)
                    {
                        nextPos.X = nextPos.X + ((toPosition.X > nextPos.X) ? 1 : -1);
                    }

                    if (nextPos.Y != toPosition.Y)
                    {
                        nextPos.Y = nextPos.Y + ((toPosition.Y > nextPos.Y) ? 1 : -1);
                    }
                    route.Add(nextPos);
                }
            }
            while (nextPos.X != toPosition.X || nextPos.Y != toPosition.Y);

            return route;
        }

        public string getDirectionTo(Vector2 fromPosition, Vector2 toPosition)
        {

            if (fromPosition.X > toPosition.X)
            {
                return "Right";
            }
            else if (fromPosition.X < toPosition.X)
            {
                return "Left";
            }
            else if (fromPosition.Y > toPosition.Y)
            {
                return "Down";
            }
            else if (fromPosition.Y < toPosition.Y)
            {
                return "Up";
            }

            return "Down";
        }


        #endregion


    }
}
